package com.bds.portal.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.impl.NutDao;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bds.model.Hosts;
import com.bds.model.Result;
import com.bds.model.TNode;
import com.bds.model.Task;
import com.bds.model.Template;
import com.bds.model.TemplateDetail;
import com.bds.model.TemplateUrl;
import com.bds.portal.util.Const;
import com.bds.portal.util.HTMLUploadOSSUtil;

import shaded.org.apache.commons.lang3.StringUtils;

@Component
public class TempletService {
	private static Logger logger = Logger.getLogger(TempletService.class);

	@Resource
	private NutDao portalDao;
	@Resource
	private MyTUrlService myTUrlService;

	public Result addTemplateDetail(String requestId, String columnName, String type, String thinkDataId, String attr,
			Integer orderby, String cssPath) {
		Result result = new Result();

		List<TNode> nodeArray = new ArrayList<TNode>();

		try {
			String html = HTMLUploadOSSUtil.downloadHtml(requestId);
			// Task task = portalDao.fetch(Task.class, Cnd.where("request_id",
			// "=", requestId));

			Document doc = Jsoup.parse(html);

			List<TemplateDetail> tlist = new ArrayList<TemplateDetail>();

			TemplateDetail templateDetail = new TemplateDetail();
			templateDetail.setCreate_time(new Date());
			templateDetail.setColumn_name(columnName);
			templateDetail.setColumn_type(type);
			templateDetail.setRequest_id(requestId);
			templateDetail.setOrderby(orderby);

			/**
			 * 解析列表或者单个元素的cssSelector
			 */
			String uuid = UUID.randomUUID().toString().replaceAll("-", "");
			Element nodeTag = null;
			if (StringUtils.isNotEmpty(thinkDataId)) {
				nodeTag = doc.getElementsByAttributeValue(Const.THINKDATA_ID, thinkDataId).first();
			} else {
				nodeTag = doc.select(cssPath).first();
			}

			String tagName = nodeTag.tagName();
			String cssSelector = nodeTag.cssSelector();
			// int siblingIndex =
			// doc.select(cssSelector).first().siblingIndex();
			// int siblingIndex = -1;

			templateDetail.setUnique_id(uuid);
			Integer index = 0;
			if (type.equals(Const.TYPE_LIST)) {
				index = 0;
				String[][] tmp = parseListCssSelector(cssSelector, doc);
				String merge = "";

				for (int i = 0; i < tmp.length; i++) {
					merge += tmp[0][i];
					if (tmp[1][0] != null) {
						// urlMerge += tmp[1][i];
					}
					if (i == 0) {
						templateDetail.setList_path(tmp[0][i]);
					} else {
						templateDetail.setNode_path(tmp[0][i]);
					}
				}
				// 获取与传来的元素类似的所有元素
				Elements eles = doc.select(merge);

				nodeArray = parseElements(eles, templateDetail, attr, requestId);

			} else {
				index = 1;
				nodeArray = parseElements(doc.select(cssSelector), templateDetail, attr, requestId);

				templateDetail.setNode_path(cssSelector);
			}

			String th = "<th index=" + index + "  uuid='" + uuid + "'><a href='javascript:void(0)'>" + columnName
					+ " </a> " + this.getButtons(uuid, templateDetail) + " </th>";
			templateDetail.setAttr(attr);

			templateDetail.setTh(th);

			templateDetail.setTag_name(tagName);
			templateDetail.setElements(nodeArray);
			// templateDetail.setSibling_index(siblingIndex);
			tlist.add(templateDetail);

			result.setData(tlist);

			result.setMsg("解析元素成功");
			result.setCode(Const.SUC);

			logger.info("解析元素成功：requestid：" + requestId);
		} catch (Exception e) {
			result.setData(null);

			result.setMsg("解析元素异常");
			result.setCode(Const.FAIL);

			logger.warn("解析元素异常：requestid：" + requestId, e);
		}

		return result;
	}

	private String getButtons(String uuid, TemplateDetail templateDetail) {
		String html = "" + "<div class=\"btn-group\">"
				+ "    <a href=\"#\" data-toggle=\"dropdown\" type=\"button\" class=\"btn btn-default btn-sm dropdown-toggle\">编辑<i class=\"fa fa-cogs\"></i> <span class=\"caret\"></span></a>"
				+ "    <ul role=\"menu\" class=\"dropdown-menu\">"
				+ "    	   <li><a href='javascript:void(0)' onclick=\"editTitle('" + uuid
				+ "')\">编辑标题 <i class=\"fa fa-font\"></i> </a></li>"
				+ "    	   <li><a href='javascript:void(0)' onclick=\"editCol('" + uuid + "','"
				+ templateDetail.getList_path() + "','" + templateDetail.getNode_path() + "','"
				+ templateDetail.getRequest_id() + "','" + templateDetail.getColumn_name() + "','"
				+ templateDetail.getColumn_type() + "')\">编辑元素 <i class=\"fa fa-check-square-o\"></i> </a></li>"
				+ "        <li><a href='javascript:void(0)' onclick=\"delCol('" + uuid
				+ "')\">删除列 <i class=\"fa fa-trash-o\"></i></a></li>   "
				+ "        <li><a href='javascript:void(0)' onclick=\"linkPage('" + uuid
				+ "')\">采集子页面 <i class=\"fa fa-chain\"></i></a></li>   " + "    </ul></div>";
		// + " <li><a href='javascript:void(0)' onclick=\"addCell('" + uuid+
		// "')\">增加单元 <i class=\"fa fa-arrows-v\"></i></a></li>" + " </ul>" +
		// "</div>";
		return html;
	}

	public Result addTemplate(Template tp, JSONArray rows, Long userId) {
		Result result = new Result();
		String requestId = tp.getRequest_id();
		String templateName = tp.getTemplate_name();
		Long pid = tp.getPid();

		Template oldtp = portalDao.fetch(Template.class, Cnd.where("request_id", "=", requestId));

		Task task = portalDao.fetch(Task.class, Cnd.where("request_id", "=", requestId));
		String url = task.getUrl();
		if (!url.startsWith("http")) {
			url = "http://" + url;
		}
		tp.setUrl(url);
		try {
			java.net.URL u = new java.net.URL(url);
			String host = u.getHost();// 获取主机名
			Hosts p = portalDao.fetch(Hosts.class, Cnd.where("website", "=", host).and("user_id", "=", userId));
			if (oldtp != null) {

				if (!templateName.equals(oldtp.getTemplate_name())) {
					List<Template> oldList = portalDao.query(Template.class,
							Cnd.where("user_id", "=", userId).and("template_name", "=", templateName));

					if (oldList != null && oldList.size() > 0) {
						result.setCode(Const.FAIL);
						result.setMsg("此模板命名已存在，请重新命名");
						return result;
					}

				}
				tp.setId(oldtp.getId());
				if (tp.getHost_id() == null) {
					tp.setHost_id(p.getId());
				}
				portalDao.clear(TemplateDetail.class, Cnd.where("tid", "=", oldtp.getId()));
			} else {

				List<Template> oldList = portalDao.query(Template.class,
						Cnd.where("user_id", "=", userId).and("template_name", "=", templateName));

				if (oldList != null && oldList.size() > 0) {
					result.setCode(Const.FAIL);
					result.setMsg("此模板命名已存在，请重新命名");
					return result;
				}

				tp.setUrl(url);

				tp.setCreate_time(new Date());
				portalDao.insert(tp);
			}

			if (p == null) {
				p = new Hosts();
				p.setCreate_time(new Date());
				p.setProject_id(pid);
				p.setWebsite(host);
				p.setUser_id(userId);
				portalDao.insert(p);

			}
			tp.setHost_id(p.getId());

			List<JSONObject> list = new ArrayList<JSONObject>();
			for (int i = 0; i < rows.size(); i++) {
				JSONObject row = rows.getJSONObject(i);
				list.add(row);
			}

			Collections.sort(list, new Comparator<JSONObject>() {
				public int compare(JSONObject arg0, JSONObject arg1) {
					return arg0.getInteger("orderby").compareTo(arg1.getInteger("orderby"));
				}
			});

			for (JSONObject row : list) {

				TemplateDetail detail = JSONObject.parseObject(row.toJSONString(), TemplateDetail.class);

				detail.setUser_id(userId);
				detail.setRequest_id(tp.getRequest_id());
				detail.setCreate_time(new Date());
				detail.setTid(tp.getId());
				detail.setPropert("prop" + row.getInteger("orderby"));

				portalDao.fastInsert(detail);

			}

			int max = portalDao.func(TemplateDetail.class, "MAX", "orderby");

			List<TemplateDetail> details = portalDao.query(TemplateDetail.class,
					Cnd.where("tid", "=", tp.getId()).asc("orderby"));
			Map<String, TemplateDetail> map = new LinkedHashMap<String, TemplateDetail>();

			StringBuffer head = new StringBuffer();
			StringBuffer title = new StringBuffer();
			JSONArray array = new JSONArray();
			for (TemplateDetail d : details) {
				String key = d.getPropert();
				if (!map.containsKey(key)) {
					map.put(key, d);
					head = head.append(key + ",");
					title = title.append(d.getColumn_name() + ",");
				}
				JSONObject o = new JSONObject();
				o.put("prop", d.getPropert());
				o.put("len", d.getNode_length());
				array.add(o);
			}

			if (head.length() > 0) {
				head = head.deleteCharAt(head.length() - 1);
			}
			if (title.length() > 0) {
				title = title.deleteCharAt(title.length() - 1);
			}
			tp.setProps(array.toJSONString());
			tp.setTitle(title.toString());
			tp.setHead(head.toString());
			logger.info("props:" + tp.getProps() + ",title:" + tp.getTitle() + ",head:" + tp.getHead());
			String[] tarry = tp.getTitle().split(",");
			head = new StringBuffer();
			title = new StringBuffer();
			List<String> tlist = new ArrayList<String>(Arrays.asList(tarry));
			String[] harry = tp.getHead().split(",");
			List<String> hlist = new ArrayList<String>(Arrays.asList(harry));
			JSONObject json = new JSONObject();
			if (StringUtils.isNotEmpty(tp.getExts())) {
				String[] row = tp.getExts().split(",");

				for (int i = 0; i < row.length; i++) {

					String[] ks = row[i].split("\\|");
					json.put(ks[0], ks[1]);
					String key = "ext" + i;
					if (!hlist.contains(key)) {
						hlist.add(key);
					}
					if (!tlist.contains(ks[0])) {
						tlist.add(ks[0]);
					}

				}
			}

			for (String t : tlist) {
				title = title.append(t + ",");
			}
			for (String h : hlist) {
				head = head.append(h + ",");
			}
			if (title.length() > 0) {
				title = title.deleteCharAt(title.length() - 1);
			}

			if (head.length() > 0) {
				head = head.deleteCharAt(head.length() - 1);
			}
			logger.info("props:" + tp.getProps() + ",title:" + tp.getTitle() + ",head:" + tp.getHead());
			tp.setColumns(max);
			tp.setTitle(title.toString());
			tp.setHead(head.toString());

			tp.setUpdate_time(new Date());
			portalDao.updateIgnoreNull(tp);

			portalDao.clear(TemplateUrl.class, Cnd.where("request_id", "=", requestId));
			if (tp.getType().equals("click") || tp.getType().equals("pull") || tp.getType().equals("ajax")) {
				myTUrlService.saveTUrl(tp.getUser_id(), tp.getUrl_list(), requestId);
			} else if (tp.getType().equals("list") || tp.getType().equals("url")) {
				String prule = tp.getPage_rule();

				int index = prule.indexOf("[[");
				int last = prule.indexOf("]]");
				int length = prule.length();
				if (index > 0 && last > 0) {
					String furl = prule.substring(0, index);
					String lurl = null;
					if (last + 2 == length) {
						lurl = "";
					} else {
						lurl = prule.substring(last + 2, prule.length());
					}

					String maxp = prule.substring(index + 2, last);
					int pmin = 1;
					int pmax = 1;

					if (maxp.split("\\|").length > 1) {
						String pp = maxp.split("\\|")[0];
						String init = maxp.split("\\|")[1];
						pmin = Integer.parseInt(pp.split("-")[0]);
						pmax = Integer.parseInt(pp.split("-")[1]);
						// int b = Integer.parseInt(init.split("-")[0]);
						int e = Integer.parseInt(init);

						for (int i = pmin; i <= pmax; i++) {
							String pageUlr = furl + (i * e) + lurl;

							TemplateUrl tpurl = new TemplateUrl();
							tpurl.setRequest_id(requestId);
							tpurl.setUser_id(tp.getUser_id());
							tpurl.setStatus(0);
							tpurl.setUrl(pageUlr);
							tpurl.setOrderby(i);
							tpurl.setCreate_time(new Date());
							tpurl.setSend_status(0);
							portalDao.fastInsert(tpurl);
						}
					} else {
						pmin = Integer.parseInt(maxp.split("-")[0]);
						pmax = Integer.parseInt(maxp.split("-")[1]);

						for (int i = pmin; i <= pmax; i++) {
							String pageUlr = furl + i + lurl;
							TemplateUrl tpurl = new TemplateUrl();
							tpurl.setRequest_id(requestId);
							tpurl.setUser_id(tp.getUser_id());
							tpurl.setStatus(0);
							tpurl.setUrl(pageUlr);
							tpurl.setOrderby(i);
							tpurl.setCreate_time(new Date());
							tpurl.setSend_status(0);
							portalDao.fastInsert(tpurl);
						}
					}

				} else {

					TemplateUrl tpurl = new TemplateUrl();
					tpurl.setRequest_id(requestId);
					tpurl.setUser_id(tp.getUser_id());
					tpurl.setStatus(0);
					tpurl.setSend_status(0);
					tpurl.setUrl(tp.getUrl());
					tpurl.setCreate_time(new Date());
					tpurl.setOrderby(1);
					portalDao.fastInsert(tpurl);

				}
			}

			result.setCode(Const.SUC);

			result.setMsg("创建成功");

			logger.info("插入template成功：userId:" + userId + ",requestId:" + requestId);
		} catch (Exception e) {
			result.setCode(Const.FAIL);

			result.setMsg("创建异常");

			logger.error("插入template异常：userId:" + userId + ",requestId:" + requestId, e);
		}

		return result;
	}

	/**
	 * 分解cssSelector， 第一部分：列表分支之前的（用于循环） 第二部分：列表分支之后的（用于取值）
	 * 若包含url，则二维数组中r[1][0],r[1][1]放url
	 */
	private String[][] parseListCssSelector(String cssSelector, Document doc) {
		String[][] result = new String[2][2];
		String r1 = "", r2 = "";
		String tmp = "";

		/*
		 * if (cssSelector.indexOf("#") == 0) { try { String ele =
		 * tmp.substring(0, tmp.indexOf(">")); String tagName =
		 * doc.getElementById(ele.replace("#", "")).tagName();
		 * 
		 * tmp = tmp.replaceAll(ele, tagName); } catch (Exception e) {
		 * result[0][0] = tmp; result[0][1] = ""; return result; } }
		 */

		// 只取class的第一部分
		for (String classes : cssSelector.split(">")) {
			String[] classesArray = classes.split("\\.", 3);
			switch (classesArray.length) {
			case 1: {
				tmp = tmp + ">" + classesArray[0];
				break;
			}
			case 2: {
				tmp = tmp + ">" + classesArray[0] + "." + classesArray[1];
				break;
			}
			case 3: {
				tmp = tmp + ">" + classesArray[0] + "." + classesArray[1] + "." + classesArray[2];
				break;
			}
			}
		}

		tmp = tmp.substring(1).replaceAll(" ", "");
		try {
			r1 = tmp.substring(0, tmp.lastIndexOf(":"));
			result[0][0] = r1;

			try {
				r2 = tmp.replace(r1, "").substring(tmp.replace(r1, "").indexOf(">"));
				String r2Tmp = r2.split(">")[r2.split(">").length - 1];
				String[] nodeTmp = r2Tmp.split("\\.");
				if (nodeTmp.length > 1) {
					r2 = r2.replace(r2Tmp, nodeTmp[0] + "." + nodeTmp[1]);
				}
				result[0][1] = r2;
			} catch (Exception e) {
				result[0][1] = "";
				// logger.error("r2异常", e);
			}
		} catch (Exception e) {

			result[0][0] = tmp;
			result[0][1] = "";
			// return result;
		}

		String[] selectorTmp = (result[0][0] + result[0][1]).split(">");
		String preNode = "";// 记录前一次循环的元素节点

		/**
		 * 从最后一级往上找，直到找到元素数量大于1的为止
		 */
		for (int i = selectorTmp.length - 1; i >= 0; i--) {
			String parentNodeTmp = "";

			// 拼接上一级元素
			for (int j = 0; j <= i; j++) {
				parentNodeTmp = parentNodeTmp + selectorTmp[j] + ">";
			}

			if (i != 0) {
				// 如果元素数量大于1时的操作
				if (doc.select(parentNodeTmp.substring(0, parentNodeTmp.length() - 1)).size() > 1) {
					// 标明是否真的满足条件，用来去除兄弟节点相同path的情况,
					// 计算后，若flag>1,则满足
					int flag = 0;
					for (int c = 0; c < doc.select(parentNodeTmp.substring(0, parentNodeTmp.length() - 1))
							.size(); c++) {
						Node node = doc.select(parentNodeTmp.substring(0, parentNodeTmp.length() - 1)).get(c);
						Node parentNode;
						if (i == selectorTmp.length - 1) {
							parentNode = doc.select(cssSelector).first();
						} else {
							parentNode = doc.select(cssSelector).parents().get(selectorTmp.length - 2 - i);
						}
						if (node.attr(Const.THINKDATA_ID).equals(parentNode.attr(Const.THINKDATA_ID))) {
							flag += 1;
							// 减少多余循环，一旦大于1了，尽早跳出
							if (flag > 1) {
								break;
							}
						}
					}
					// 若计算后，flag<=1，则进入上一级继续判断
					if (flag <= 1) {
						preNode = parentNodeTmp;
						continue;
					}
					// 如果在不是最后一级（即不是第一次循环）满足元素数量大于1了，
					// 则将该元素后一级的tag替换原来的值
					// （原来的值可能包含类名，id等，即div.className被替换成div，因为className是特殊属性）
					if (i < selectorTmp.length - 1) {
						selectorTmp[i + 1] = doc.select(preNode.substring(0, preNode.length() - 1)).get(0).tag()
								.getName();
					} else {
						// 如果在最后一级就满足了元素数量大于1，则说明是正确的，不用特殊处理了
						break;
					}
					// 拼接新的cssSelector
					String newCss = "";
					for (int j = 0; j < selectorTmp.length; j++) {
						newCss = newCss + selectorTmp[j] + ">";
					}
					// 用新的cssSelector替换原来的
					if (result[0][1].equals("")) {
						result[0][0] = newCss.substring(0, newCss.length() - 1);
					} else {
						result[0][1] = newCss.substring(0, newCss.length() - 1).replace(result[0][0], "");
					}
					break;
				} else {
					// 如果不满足元素数量大于1，则记录本次循环的元素，该元素作为下一次循环的后一级元素
					preNode = parentNodeTmp;
				}
			} else {
				// 如果到第一级还没找到满足元素数量大于1的情况，则说明第一级就是特殊的，取第一级的tag即可
				parentNodeTmp = doc.select(parentNodeTmp.substring(0, parentNodeTmp.length() - 1)).get(0).tag()
						.getName();
				selectorTmp[0] = parentNodeTmp;
				String newCss = "";
				for (int j = 0; j < selectorTmp.length; j++) {
					newCss = newCss + selectorTmp[j] + ">";
				}
				if (result[0][1].equals("")) {
					result[0][0] = newCss.substring(0, newCss.length() - 1);
				} else {
					result[0][0] = newCss.substring(0, newCss.length() - 1).replace(result[0][1], "");
				}
			}
		}

		// 递归，获取对应的url
		Elements childNodes = doc.select(cssSelector).get(0).children();
		for (Element e : childNodes) {
			if (!e.attr("href").equals("") && !e.attr("href").startsWith("javascript")) {
				result[1][0] = result[0][0];
				result[1][1] = result[0][1] + ">" + e.tagName();
				break;
			} else {
				String nodePath = e.cssSelector();
				parseListCssSelector(nodePath, doc);
			}
		}

		return result;
	}

	public Result delTemplateDetail(String uniqueId) {
		Result result = new Result();
		try {
			// detail应该在删除模板的时候关联删除
			// portalDao.clear(TemplateDetail.class, Cnd.where("unique_id", "=",
			// uniqueId));
			result.setData(null);

			result.setMsg("删除column成功");
			result.setCode(Const.SUC);
			logger.info("删除column成功：unique_id：" + uniqueId);
		} catch (Exception e) {
			result.setData(null);

			result.setMsg("删除column失败");
			result.setCode(Const.FAIL);
			logger.error("删除column失败：unique_id：" + uniqueId, e);
		}
		return result;
	}

	public Result updTemplateDetailEle(Long id, String request_id, String cname, String ctype, String list_path,
			String node_path) {
		Result result = new Result();
		try {
			String html = HTMLUploadOSSUtil.downloadHtml(request_id);
			Template task = portalDao.fetch(Template.class, Cnd.where("request_id", "=", request_id));
			Document doc = Jsoup.parse(html, "utf-8");
			Elements eles = doc.select(list_path + node_path);
			int siblingIndex = eles.first().siblingIndex();
			if (!eles.isEmpty()) {
				int max = eles.size();
				if (max > task.getRows()) {
					portalDao.update(Template.class, Chain.make("rows", max), Cnd.where("id", "=", task.getId()));
				}
			}

			portalDao.update(
					TemplateDetail.class, Chain.make("column_name", cname).add("column_type", ctype)
							.add("list_path", list_path).add("node_path", node_path).add("sibling_index", siblingIndex),
					Cnd.where("id", "=", id));
			result.setMsg("更新成功");
			result.setCode(Const.SUC);

		} catch (Exception e) {

			result.setMsg("更新column失败");
			result.setCode(Const.FAIL);
			logger.error("更新column失败");
		}
		return result;
	}

	public Result getTemplateDetail(String requestId) {
		Result result = new Result();
		try {
			String html = HTMLUploadOSSUtil.downloadHtml(requestId);
			Document doc = Jsoup.parse(html, "utf-8");
			List<TemplateDetail> details = portalDao.query(TemplateDetail.class,
					Cnd.where("request_id", "=", requestId));
			details = parseDetail(details, doc, requestId);

			// Task task = portalDao.fetch(Task.class, Cnd.where("request_id",
			// "=", requestId));
			// String json = task.getJson();
			// JSONArray array = JSONArray.parseArray(json);
			result.setData(details);
			result.setCode(Const.SUC);
			logger.info("获取模板detail成功：requestId：" + requestId);
		} catch (Exception e) {
			result.setData(null);

			result.setMsg("获取模板detail失败");
			result.setCode(Const.FAIL);
			logger.error("获取模板detail失败：requestId：" + requestId);
		}
		return result;
	}

	public List<TemplateDetail> parseDetail(List<TemplateDetail> details, Document doc, String request_id) {

		for (TemplateDetail detail : details) {
			int index = 0;
			if (detail.getColumn_type().equals(Const.TYPE_LIST)) {
				index = 0;
			} else {
				index = 1;
			}
			String th = "<th index=" + index + "  uuid='" + detail.getUnique_id() + "'><a href='javascript:void(0)'>"
					+ detail.getColumn_name() + " </a> " + this.getButtons(detail.getUnique_id(), detail) + " </th>";
			detail.setTh(th);
			detail.setElements(parseElements(doc.select(detail.getList_path() + detail.getNode_path()), detail,
					detail.getAttr(), request_id));

		}
		return details;
	}

	/**
	 * 表示是取url还是普通元素，url：1，普通：0
	 */
	private List<TNode> parseElements(Elements elements, TemplateDetail node, String attr, String request_id) {
		List<TNode> nodes = new ArrayList<TNode>();
		Task t = portalDao.fetch(Task.class, Cnd.where("request_id", "=", request_id));
		Integer length = 0;
		for (Element e : elements) {

			String thinkDataIdTmp = e.attr(Const.THINKDATA_ID);
			String attrVal = "";
			if (attr.equals("text")) {
				attrVal = e.text();
			} else {
				attrVal = e.attr(attr);
			}

			String tag = e.tagName();
			// 若没有href或者src，则试着去子节点里找，看看有没有，
			// 例如<div><a href='http://' /></div> 就属于这种情况
			String td = "";
			TNode tnode = new TNode();
			tnode.setId(thinkDataIdTmp);

			if (StringUtils.isNotEmpty(attrVal)) {
				if (attrVal.length() > length) {
					length = attrVal.length() * 2;
				}
			}

			tnode.setTag(tag);

			if (StringUtils.isEmpty(attrVal)) {
				Elements childNodes = e.children();
				while (childNodes.size() > 0) {
					for (Element tmp : childNodes) {
						childNodes = tmp.children();
						if (attr.equals("text")) {
							attrVal = tmp.text();
						} else {
							attrVal = tmp.attr(attr);
						}

						if (StringUtils.isNotEmpty(attrVal)) {
							break;
						}
					}
					if (StringUtils.isNotEmpty(attrVal)) {
						break;
					}
				}
			}

			if (attr.equals("href")) {
				if (attrVal.startsWith("/")) {
					attrVal = "http://" + t.getHost() + attrVal;
				} else if (attrVal.startsWith(".")) {
					attrVal = attrVal.substring(1, attrVal.length());
					if (attrVal.startsWith("/")) {
						attrVal = "http://" + t.getHost() + attrVal;
					} else {
						attrVal = "http://" + t.getHost() + "/" + attrVal;
					}
				} else {
					if (attrVal.indexOf("http://") < 0) {
						attrVal = "http://" + t.getHost() + "/" + attrVal;
					}
				}

			}
			td = "<td class='tdspan'  uuid='" + node.getUnique_id() + "'>" + attrVal + "</td>";
			tnode.setValue(attrVal);

			tnode.setTd(td);
			nodes.add(tnode);
		}
		if (length < 128) {
			length = 128;
		}
		node.setNode_length(length);

		return nodes;
	}

	public Result getElePath(String requestId, String thinkid) {
		Result ret = new Result();
		try {
			String html = HTMLUploadOSSUtil.downloadHtml(requestId);
			Document doc = Jsoup.parse(html, "utf-8");
			Element nodeTag = doc.getElementsByAttributeValue(Const.THINKDATA_ID, thinkid).first();
			String tagName = nodeTag.tagName();
			String cssSelector = nodeTag.cssSelector();
			ret.setCode(Const.SUC);
			ret.setData(cssSelector);
		} catch (Exception e) {
			ret.setResult(Const.FAIL, "解析异常");
		}
		return ret;

	}

	public Result getElePathHtml(String listPath, String nodePath, String requestId, String columnType, String attr,
			Integer islikie) {
		Result result = new Result();
		try {
			String html = HTMLUploadOSSUtil.downloadHtml(requestId);
			Document doc = Jsoup.parse(html, "utf-8");
			Task t = portalDao.fetch(Task.class, Cnd.where("request_id", "=", requestId));
			Elements eles = doc.select(listPath + nodePath);

			if (columnType.equals(Const.TYPE_LIST)) {
				if (StringUtils.isEmpty(attr)) {
					result.setData(eles.outerHtml());
				} else {
					String ohtml = "";

					for (Element e : eles) {

						String attrVal = "";
						if (attr.equals("text")) {
							attrVal = e.text();
						} else {
							attrVal = e.attr(attr);

						}

						if (StringUtils.isEmpty(attrVal)) {
							Elements childNodes = e.children();
							while (childNodes.size() > 0) {
								for (Element tmp : childNodes) {
									childNodes = tmp.children();
									if (attr.equals("text")) {
										attrVal = tmp.text();
									} else {
										attrVal = tmp.attr(attr);
									}

									if (StringUtils.isNotEmpty(attrVal)) {
										break;
									}
								}
								if (StringUtils.isNotEmpty(attrVal)) {
									break;
								}
							}
							if (attr.equals("href")) {
								if (attrVal.startsWith("/")) {
									attrVal = "http://" + t.getHost() + attrVal;
								} else if (attrVal.startsWith(".")) {
									attrVal = attrVal.substring(1, attrVal.length());
									if (attrVal.startsWith("/")) {
										attrVal = "http://" + t.getHost() + attrVal;
									} else {
										attrVal = "http://" + t.getHost() + "/" + attrVal;
									}
								} else {
									if (attrVal.indexOf("http://") < 0) {
										attrVal = "http://" + t.getHost() + "/" + attrVal;
									}
								}
							}
						} else {
							if (attr.equals("href")) {
								if (attrVal.startsWith("/")) {
									attrVal = "http://" + t.getHost() + attrVal;
								} else if (attrVal.startsWith(".")) {
									attrVal = attrVal.substring(1, attrVal.length());
									if (attrVal.startsWith("/")) {
										attrVal = "http://" + t.getHost() + attrVal;
									} else {
										attrVal = "http://" + t.getHost() + "/" + attrVal;
									}
								} else {
									if (attrVal.indexOf("http://") < 0) {
										attrVal = "http://" + t.getHost() + "/" + attrVal;
									}
								}
							}
						}
						ohtml = ohtml + attrVal + "\n";

					}
					result.setData(ohtml);
				}

			} else {
				if (eles.isEmpty()) {
					result.setData("");
				} else {
					result.setData(eles.first().html());
				}

			}
			result.setCode(Const.SUC);
			return result;
		} catch (Exception e) {
			result.setData("");
			result.setCode(Const.FAIL);
			return result;
		}

	}

	/**
	 * 回显示
	 * 
	 * @param listPath
	 * @param nodePath
	 * @param requestId
	 * @param columnName
	 * @param columnType
	 * @return
	 */

	public Result parseElePath(String listPath, String nodePath, String requestId, String columnName, String columnType,
			String attr, Integer orderby, Integer islike) {
		Result result = new Result();
		try {
			String html = HTMLUploadOSSUtil.downloadHtml(requestId);
			// Task task = portalDao.fetch(Task.class, Cnd.where("request_id",
			// "=", requestId));
			Document doc = Jsoup.parse(html);
			Elements eles = doc.select(listPath + nodePath);

			TemplateDetail templateDetail = new TemplateDetail();
			templateDetail.setCreate_time(new Date());
			templateDetail.setColumn_name(columnName);
			templateDetail.setColumn_type(columnType);
			templateDetail.setRequest_id(requestId);
			templateDetail.setList_path(listPath);
			// templateDetail.setSibling_index(siblingIndex);
			templateDetail.setOrderby(orderby);
			templateDetail.setNode_path(nodePath);
			String uuid = UUID.randomUUID().toString().replaceAll("-", "");
			templateDetail.setUnique_id(uuid);
			List<TNode> nodeArray = parseElements(eles, templateDetail, attr, requestId);
			int indexType = 0;
			if (columnType.equals(Const.TYPE_LIST)) {
				indexType = 0;
				templateDetail.setElements(nodeArray);
			} else {
				indexType = 1;
				TNode f = nodeArray.get(0);
				List<TNode> flist = new ArrayList<TNode>();
				flist.add(f);
				templateDetail.setElements(flist);
			}

			String th = "<th index=" + indexType + "  uuid='" + uuid + "'><a href='javascript:void(0)'>" + columnName
					+ " </a> " + this.getButtons(uuid, templateDetail) + " </th>";
			templateDetail.setAttr(attr);

			templateDetail.setTh(th);

			result.setData(templateDetail);

			result.setMsg("编辑模板detail元素成功");
			result.setCode(Const.SUC);
			logger.info("编辑模板detail元素成功：requestId：" + requestId);
		} catch (Exception e) {
			result.setData(null);

			result.setMsg("编辑模板detail元素失败");
			result.setCode(Const.FAIL);
			logger.error("编辑模板detail元素失败：requestId：" + requestId);
		}
		return result;
	}

}
